#!/bin/bash
readonly ver=1
readonly name=("b" "c" "m" "bf" "cf" "mf")
readonly def=("brew" "brew cask" "mas" "HomeBrew" "HomeBrew Cask" "Mac App Store")
readonly pm=3
# NOTE the name of the package managers must be at first
# NOTE the constant "pm" is the amount of the package managers
detect(){
	if [ ! -n "$1" ];then
		if [ ! -n "$2" ];then
			echo "Wrong command usage!"
		fi
		return 1
	else
		return 0
	fi
}
consist(){
	if [ ! -n "$2" ];then
		set "$1" 0 ${#name[*]}
	fi
	if [ ! -n "$3" ];then
		set "$1" 0 "$2"
	fi
	for((loop=$2;loop<$3;loop++))
	do
		if [ "${name[$loop]}" == "$1" ];then
			return 0
		fi
	done
	return 1
}
finddef(){
	length=${#name[*]}
	for((loop=0;loop<$length;loop++))
	do
		if [ "${name[$loop]}" == "$1" ];then
			#return $loop
			echo -n "${def[$loop]}"
			return 0
		fi
	done
	return 1
}
ulconvert(){
	for((loop=0;loop<${#1};loop++))
	do
		ascii=$(printf "%d" "'${1:$loop:1}")
		if [[ $ascii -le 122 && $ascii -ge 97 ]];then
			printf \\x$(printf %x $[$ascii-32])
		else
			echo -n ${1:$loop:1}
		fi
	done
}
myseq(){
	if [ ! -n "$2" ];then
		set 1 $1
	fi
	if [ $1 -gt $2 ];then
		for((loop=$1;loop>=$2;loop--))
		do
			echo $loop
		done
	elif [ $1 -lt $2 ];then
		for((loop=$1;loop<=$2;loop++))
		do
			echo $loop
		done
	else
		echo $1
	fi
}
match(){
	#typeset -u big
	#typeset -i small
	check=$1
	for loop in $(myseq 2 $#)
	do
		shift
		big="$(ulconvert $1)"
		small="$1"
		if [[ "$check" == "$big" || "$check" == "$small" ]];then
			return 0
		fi
	done
	echo "Options do not match!"
	return 1
}
echores(){
	echo
	if [ -n "$result" ];then
		echo "$result"
	else
		echo "Package not found."
	fi
	echo
}
list(){
	if consist "$1" "$pm";then
		echo "`finddef "$1""f"`:"
		result=`ls "$HOME/.mask/$1"`
		echores
	fi
}
if [ ! -d "$HOME/.mask" ];then
	mkdir -p "$HOME/.mask"
fi
mkdir -p "$HOME/.mask/b" "$HOME/.mask/c" "$HOME/.mask/m"
# FIXME whether the symlink is not linked to itself
if [ ! -h "/usr/local/bin/mask" ];then
	ln -s "$0" /usr/local/bin/mask
fi
echo
if [ ! -n "$1" ];then
	echo 'No option found! You can try `mask install <name>` or `mask search <name>`'
	echo
	exit 1
fi
case "$1" in
"install")
# TODO auto detect
if detect "$2";then
	echo "Which Package Manager do you want to install from?"
	read -p "[B]rew | brew [C]ask | [M]as " -s -n 1 select
	echo
	if match "$select" "b" "c" "m";then
		#case $select in
		#"b")
		#brew install "$2"
		#;;
		#"c")
		#brew cask install "$2"
		#;;
		#"m")
		#mas install "$2"
		#;;
		#esac
		# FIXME some package managers do not use install to install a package
		echo
		eval "`finddef "$select"`" install "$2"
		if [ "$?" == "0" ];then
			mkdir -p "$HOME/.mask/$select/$2"
		fi
		# FIXME check more than the return value to know if the installation is successful or not
		# TODO write more informations to the installation folder
	fi
fi
;;
# TODO installb/~c/~p/~f/~m/~a
"search")
# [B]rew | brew [C]ask | [P]ort | [F]ink | [M]as | ...
# TODO : [A]pt | [P]ort | [F]ink
if detect "$2";then
	# XXX detect if the package exists
	#echo "HomeBrew:"
	echo "`finddef bf`"
	result="`brew search "$2" --formulae 2>/dev/null`"
	echores
	#echo "HomeBrew Cask:"
	echo "`finddef cf`"
	result="`brew search "$2" --casks 2>/dev/null`"
	echores
	#echo "Mac App Store:"
	echo "`finddef mf`"
	result="`mas search "$2"`"
	echores
fi
;;
"list")
# FIXME cannot list packages not installed by mask
if detect "$2" no;then
	if match "$2" "b" "c" "m";then
		list "$2"
	fi
else
	for((loop=0;loop<$pm;loop++))
	do
		list "${name[$loop]}"
	done
fi
;;
"uninstall")
# TODO
;;
"update")
if [ $(curl -s "https://gitee.com/scientificworld/mask/raw/master/version") -gt $ver ];then
	echo "Updating Mask..."
	curl -o "$0" -s https://gitee.com/scientificworld/mask/raw/master/mask_current/mask
	chmod +x "$0"
	echo "Mask has been updated."
else
	echo "Mask is up to date."
fi
;;
"run")
if detect "$2";then
	if match "$2" "b" "c" "m";then
		cmd="$2"
		shift 2
		eval "`finddef "$cmd"`" "$@"
	fi
fi
;;
"help")
cat <<- eof
mask - The Mixture of serveral command line package managers
version $ver

commands:
install
search
list
update
run
help
eof
;;
*)
echo 'Command not found! You can try `mask install <name>` or `mask search <name>`'
echo
exit 1
;;
esac
echo
exit 0
